package graphs;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Abstract class, extended by Scatter plot and Line Graph.
 * 
 * @author Lindsay Kubasik, Trevor Terris
 * 
 */
@SuppressWarnings("serial")
public abstract class AbstractNumericalPlot extends
        AbstractGraph<Object, List<Object>>
{
    /**
     * find the min and max x values of a given set of data
     * 
     * @param myData
     * @param myXvals
     * @return
     */
    protected double[] findXMinMax(Map<Object, List<Object>> myData,
            Set<Object> myXvals)
    {
        double xMin = 0, xMax = 0;
        double[] xMinMax = new double[2];

        for (Object xVal : myXvals)
        {
            if (xVal instanceof Double)
            {
                if ((Double) xVal > xMax)
                {
                    xMinMax[0] = (Double) xVal;
                    xMax = (Double) xVal;
                }
                if ((Double) xVal < xMin)
                {
                    xMinMax[1] = (Double) xVal;
                    xMin = (Double) xVal;
                }
            }
        }
        return xMinMax;
    }

    /**
     * does the drawing of the graph for these types of plots, it generates axis
     * and label markers
     * 
     * @param pen
     * @param bounds
     * @param colors
     * @param points
     * @param yMax
     * @param xMax
     * @param yMin
     * @param xMin
     * @param myXvals
     * @param myData
     * @param myLabels
     */
    protected void drawGraph(Graphics pen, Dimension bounds,
            List<Color> colors, Map<Integer, List<Point>> points, double yMax,
            double xMax, double yMin, double xMin, Set<Object> myXvals,
            Map<Object, List<Object>> myData, List<String> myLabels)
    {
        pen.drawLine(20, 0, 20, bounds.height);
        pen.drawLine(20, bounds.height - 10, bounds.width, bounds.height - 10);
        double yVal;
        int count = 0;
        for (Object xVal : myXvals)
        {
            colors.add(randomColor());
            for (int i = 0; i < myData.get(xVal).size(); i++)
            {
                yVal = (Double) myData.get(xVal).get(i);
                double percentY = (yVal - yMin) / (yMax - yMin);
                double percentX = ((Double) xVal - xMin) / (xMax - xMin);
                Dimension size = new Dimension(
                        (int) ((bounds.width - 50) * (percentX)),
                        (int) ((bounds.height - 80) * (1 - percentY) + 40));
                Point dot1 = new Point(size.width, size.height);
                pen.setColor(colors.get(i));
                plotPoints(pen, points, count, i, dot1, size);
                if (myLabels.size() > i + 1)
                    pen.drawString(myLabels.get(i + 2), 0, i * 15 + 10);
            }
            count++;
        }

        pen.setColor(Color.black);
        pen.drawString((yMax) + "", 10, 50);
        pen.drawString((yMax - yMin) / 2 + yMin + "", 10,
                ((bounds.height) / 2) + 40);
        pen.drawString((xMax) + "", bounds.width - 20, bounds.height - 5);
        pen.drawString((xMax - xMin) / 2 + xMin + "",
                ((bounds.height) / 2) - 10, bounds.height - 5);
    }

    /**
     * draws the actual points for the plotting
     * 
     * @param pen
     * @param points
     * @param count
     * @param i
     * @param dot1
     * @param size
     */
    protected abstract void plotPoints(Graphics pen,
            Map<Integer, List<Point>> points, int count, int i, Point dot1,
            Dimension size);

}
